// This is a TextMate grammar distributed by `starry-night`.
// This grammar is developed at
// <https://github.com/atom/language-coffee-script>
// and licensed `mit`.
// See <https://github.com/wooorm/starry-night> for more info.
/**
 * @import {Grammar} from '@wooorm/starry-night'
 */

/** @type {Grammar} */
const grammar = {
  dependencies: ['source.coffee', 'text.html.basic'],
  extensions: ['.litcoffee', '.coffee.md'],
  names: ['literate-coffeescript', 'litcoffee'],
  patterns: [
    {
      begin: '^(?=([ ]{4}|\\t)(?!$))',
      end: '^(?!([ ]{4}|\\t))',
      name: 'markup.raw.block.markdown',
      patterns: [{include: '#block_raw'}]
    },
    {
      begin:
        '(?x)^\n(?=  [ ]{0,3}>.\n|  [#]{1,6}\\s*+\n|  [ ]{0,3}(?<marker>[-*_])([ ]{0,2}\\k<marker>){2,}[ \\t]*+$\n)',
      end: '(?x)^\n(?!  [ ]{0,3}>.\n|  [#]{1,6}\\s*+\n|  [ ]{0,3}(?<marker>[-*_])([ ]{0,2}\\k<marker>){2,}[ \\t]*+$\n)',
      name: 'meta.block-level.markdown',
      patterns: [
        {include: '#block_quote'},
        {include: '#heading'},
        {include: '#separator'}
      ]
    },
    {
      begin: '^[ ]{0,3}([*+-])(?=\\s)',
      captures: {1: {name: 'punctuation.definition.list_item.markdown'}},
      end: '^(?=\\S|[ ]{4,})|(?!\\G)',
      name: 'markup.list.unnumbered.markdown',
      patterns: [{include: '#list-paragraph'}]
    },
    {
      begin: '^[ ]{0,3}([0-9]+\\.)(?=\\s)',
      captures: {1: {name: 'punctuation.definition.list_item.markdown'}},
      end: '^(?=\\S|[ ]{4,})|(?!\\G)',
      name: 'markup.list.numbered.markdown',
      patterns: [{include: '#list-paragraph'}]
    },
    {
      begin:
        '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\\b)(?!.*?</\\1>)',
      end: '(?<=^</\\1>$\\n)',
      name: 'meta.disable-markdown',
      patterns: [{include: 'text.html.basic'}]
    },
    {
      begin:
        '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\\b)',
      end: '$\\n?',
      name: 'meta.disable-markdown',
      patterns: [{include: 'text.html.basic'}]
    },
    {
      captures: {
        1: {name: 'punctuation.definition.constant.markdown'},
        10: {name: 'punctuation.definition.string.end.markdown'},
        11: {name: 'string.other.link.description.title.markdown'},
        12: {name: 'punctuation.definition.string.begin.markdown'},
        13: {name: 'punctuation.definition.string.end.markdown'},
        2: {name: 'constant.other.reference.link.markdown'},
        3: {name: 'punctuation.definition.constant.markdown'},
        4: {name: 'punctuation.separator.key-value.markdown'},
        5: {name: 'punctuation.definition.link.markdown'},
        6: {name: 'markup.underline.link.markdown'},
        7: {name: 'punctuation.definition.link.markdown'},
        8: {name: 'string.other.link.description.title.markdown'},
        9: {name: 'punctuation.definition.string.begin.markdown'}
      },
      match:
        '(?x)\n\\s*                    # Leading whitespace\n(\\[)(.+?)(\\])(:)      # Reference name\n[ \\t]*                 # Optional whitespace\n(<?)(\\S+?)(>?)         # The url\n[ \\t]*                 # Optional whitespace\n(?:\n  ((\\().+?(\\)))       # Match title in quotes…\n  | ((").+?("))         # or in parens.\n)?                      # Title is optional\n\\s*                    # Optional whitespace\n$',
      name: 'meta.link.reference.def.markdown'
    },
    {
      begin: '^(?=\\S)(?![=-]{3,}(?=$))',
      end: '^(?:\\s*$|(?=[ ]{0,3}>.))|(?=[ \\t]*\\n)(?<=^===|^====|=====|^---|^----|-----)[ \\t]*\\n|(?=^#)',
      name: 'meta.paragraph.markdown',
      patterns: [
        {include: '#inline'},
        {include: 'text.html.basic'},
        {
          captures: {1: {name: 'punctuation.definition.heading.markdown'}},
          match: '^(={3,})(?=[ \\t]*$)',
          name: 'markup.heading.1.markdown'
        },
        {
          captures: {1: {name: 'punctuation.definition.heading.markdown'}},
          match: '^(-{3,})(?=[ \\t]*$)',
          name: 'markup.heading.2.markdown'
        }
      ]
    }
  ],
  repository: {
    ampersand: {
      match: '&(?!([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+);)',
      name: 'meta.other.valid-ampersand.markdown'
    },
    block_quote: {
      begin: '\\G[ ]{0,3}(>)(?!$)[ ]?',
      beginCaptures: {1: {name: 'punctuation.definition.blockquote.markdown'}},
      end: '(?x)^\n(?=  \\s*$\n|  [ ]{0,3}(?<marker>[-*_])([ ]{0,2}\\k<marker>){2,}[ \\t]*+$\n|  [ ]{0,3}>.\n)',
      name: 'markup.quote.markdown',
      patterns: [
        {
          begin: '(?x)\\G\n(?=  [ ]{0,3}>.\n)',
          end: '^',
          patterns: [{include: '#block_quote'}]
        },
        {
          applyEndPatternLast: true,
          begin:
            '(?x)\\G\n(?=  ([ ]{4}|\\t)\n|  [#]{1,6}\\s*+\n|  [ ]{0,3}(?<marker>[-*_])([ ]{0,2}\\k<marker>){2,}[ \\t]*+$\n)',
          end: '^',
          patterns: [
            {include: '#block_raw'},
            {include: '#heading'},
            {include: '#separator'}
          ]
        },
        {
          begin:
            '(?x)\\G\n(?!  $\n|  [ ]{0,3}>.\n|  ([ ]{4}|\\t)\n|  [#]{1,6}\\s*+\n|  [ ]{0,3}(?<marker>[-*_])([ ]{0,2}\\k<marker>){2,}[ \\t]*+$\n)',
          end: '$|(?<=\\n)',
          patterns: [{include: '#inline'}]
        }
      ]
    },
    block_raw: {
      name: 'markup.raw.block.markdown',
      patterns: [{include: '#coffee_script'}]
    },
    bold: {
      begin:
        '(?x)\n(\\*\\*|__)(?=\\S)                                          # Open\n(?=\n  (\n    <[^>]*+>                                                # HTML tags\n    | (?<raw>`+)([^`]|(?!(?<!`)\\k<raw>(?!`))`)*+\\k<raw>   # Raw\n    | \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+                     # Escapes\n    | \\[\n    (\n      (?<square>                                            # Named group\n        [^\\[\\]\\\\]                                       # Match most chars\n        | \\\\.                                             # Escaped chars\n        | \\[ \\g<square>*+ \\]                             # Nested brackets\n      )*+\n      \\]\n      (\n        (                                                   # Reference Link\n          [ ]?                                              # Optional space\n          \\[[^\\]]*+\\]                                    # Ref name\n        )\n        |\n        (                                                   # Inline Link\n          \\(                                               # Opening paren\n          [ \\t]*+                                          # Optional whitespace\n          <?(.*?)>?                                         # URL\n          [ \\t]*+                                          # Optional whitespace\n          (                                                 # Optional Title\n            (?<title>[\'"])\n            (.*?)\n            \\k<title>\n          )?\n          \\)\n        )\n      )\n    )\n    | (?!(?<=\\S)\\1).                                      # Everything besides\n  )++\n  (?<=\\S)\\1                                               # Close\n)',
      captures: {1: {name: 'punctuation.definition.bold.markdown'}},
      end: '(?<=\\S)(\\1)',
      name: 'markup.bold.markdown',
      patterns: [
        {
          applyEndPatternLast: true,
          begin: '(?=<[^>]*?>)',
          end: '(?<=>)',
          patterns: [{include: 'text.html.basic'}]
        },
        {include: '#escape'},
        {include: '#ampersand'},
        {include: '#bracket'},
        {include: '#raw'},
        {include: '#italic'},
        {include: '#image-inline'},
        {include: '#link-inline'},
        {include: '#link-inet'},
        {include: '#link-email'},
        {include: '#image-ref'},
        {include: '#link-ref-literal'},
        {include: '#link-ref'}
      ]
    },
    bracket: {
      match: '<(?![a-z/?\\$!])',
      name: 'meta.other.valid-bracket.markdown'
    },
    coffee_script: {patterns: [{include: 'source.coffee'}]},
    escape: {
      match: '\\\\[-`*_#+.!(){}\\[\\]\\\\>]',
      name: 'constant.character.escape.markdown'
    },
    heading: {
      begin: '\\G(#{1,6})(?!#)\\s*(?=\\S)',
      captures: {1: {name: 'punctuation.definition.heading.markdown'}},
      contentName: 'entity.name.section.markdown',
      end: '\\s*(#*)$\\n?',
      name: 'markup.heading.markdown',
      patterns: [{include: '#inline'}]
    },
    'image-inline': {
      captures: {
        1: {name: 'punctuation.definition.string.begin.markdown'},
        10: {name: 'string.other.link.description.title.markdown'},
        11: {name: 'punctuation.definition.string.markdown'},
        12: {name: 'punctuation.definition.string.markdown'},
        13: {name: 'string.other.link.description.title.markdown'},
        14: {name: 'punctuation.definition.string.markdown'},
        15: {name: 'punctuation.definition.string.markdown'},
        16: {name: 'punctuation.definition.metadata.markdown'},
        2: {name: 'string.other.link.description.markdown'},
        3: {name: 'punctuation.definition.string.end.markdown'},
        5: {name: 'invalid.illegal.whitespace.markdown'},
        6: {name: 'punctuation.definition.metadata.markdown'},
        7: {name: 'punctuation.definition.link.markdown'},
        8: {name: 'markup.underline.link.image.markdown'},
        9: {name: 'punctuation.definition.link.markdown'}
      },
      match:
        '(?x)\n\\!                       # Images start with !\n(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\]) # Match the link text\n([ ])?                    # Space not allowed\n(\\()                     # Opening paren for url\n(<?)(\\S+?)(>?)           # The url\n[ \\t]*                   # Optional whitespace\n(?:\n  ((\\().+?(\\)))         # Match title in parens…\n  | ((").+?("))           # or in quotes.\n)?                        # Title is optional\n\\s*                      # Optional whitespace\n(\\))',
      name: 'meta.image.inline.markdown'
    },
    'image-ref': {
      captures: {
        1: {name: 'punctuation.definition.string.begin.markdown'},
        2: {name: 'string.other.link.description.markdown'},
        4: {name: 'punctuation.definition.string.begin.markdown'},
        5: {name: 'punctuation.definition.constant.markdown'},
        6: {name: 'constant.other.reference.link.markdown'},
        7: {name: 'punctuation.definition.constant.markdown'}
      },
      match:
        '\\!(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)(.*?)(\\])',
      name: 'meta.image.reference.markdown'
    },
    inline: {
      patterns: [
        {include: '#escape'},
        {include: '#ampersand'},
        {include: '#bracket'},
        {include: '#raw'},
        {include: '#bold'},
        {include: '#italic'},
        {include: '#line-break'},
        {include: '#image-inline'},
        {include: '#link-inline'},
        {include: '#link-inet'},
        {include: '#link-email'},
        {include: '#image-ref'},
        {include: '#link-ref-literal'},
        {include: '#link-ref'}
      ]
    },
    italic: {
      begin:
        '(?x)\n(\\*|_)(?=\\S)                                            # Open\n(?=\n  (\n    <[^>]*+>                                              # HTML tags\n    | (?<raw>`+)([^`]|(?!(?<!`)\\k<raw>(?!`))`)*+\\k<raw> # Raw\n    | \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+                   # Escapes\n    | \\[\n    (\n      (?<square>                                          # Named group\n        [^\\[\\]\\\\]                                     # Match most chars\n        | \\\\.                                           # Escaped chars\n        | \\[ \\g<square>*+ \\]                           # Nested brackets\n      )*+\n      \\]\n      (\n        (                                                 # Reference Link\n          [ ]?                                            # Optional space\n          \\[[^\\]]*+\\]                                  # Ref name\n        )\n        |\n        (                                                 # Inline Link\n          \\(                                             # Opening paren\n          [ \\t]*+                                        # Optional whitespace\n          <?(.*?)>?                                       # URL\n          [ \\t]*+                                        # Optional whitespace\n          (                                               # Optional Title\n            (?<title>[\'"])\n            (.*?)\n            \\k<title>\n          )?\n          \\)\n        )\n      )\n    )\n    | \\1\\1                                               # Must be bold closer\n    | (?!(?<=\\S)\\1).                                     # Everything besides\n  )++\n  (?<=\\S)\\1                                              # Close\n)',
      captures: {1: {name: 'punctuation.definition.italic.markdown'}},
      end: '(?<=\\S)(\\1)((?!\\1)|(?=\\1\\1))',
      name: 'markup.italic.markdown',
      patterns: [
        {
          applyEndPatternLast: true,
          begin: '(?=<[^>]*?>)',
          end: '(?<=>)',
          patterns: [{include: 'text.html.basic'}]
        },
        {include: '#escape'},
        {include: '#ampersand'},
        {include: '#bracket'},
        {include: '#raw'},
        {include: '#bold'},
        {include: '#image-inline'},
        {include: '#link-inline'},
        {include: '#link-inet'},
        {include: '#link-email'},
        {include: '#image-ref'},
        {include: '#link-ref-literal'},
        {include: '#link-ref'}
      ]
    },
    'line-break': {match: ' {2,}$', name: 'meta.dummy.line-break'},
    'link-email': {
      captures: {
        1: {name: 'punctuation.definition.link.markdown'},
        2: {name: 'markup.underline.link.markdown'},
        4: {name: 'punctuation.definition.link.markdown'}
      },
      match: '(<)((?:mailto:)?[-.\\w]+@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]+)(>)',
      name: 'meta.link.email.lt-gt.markdown'
    },
    'link-inet': {
      captures: {
        1: {name: 'punctuation.definition.link.markdown'},
        2: {name: 'markup.underline.link.markdown'},
        3: {name: 'punctuation.definition.link.markdown'}
      },
      match: '(<)((?:https?|ftp)://.*?)(>)',
      name: 'meta.link.inet.markdown'
    },
    'link-inline': {
      captures: {
        1: {name: 'punctuation.definition.string.begin.markdown'},
        10: {name: 'string.other.link.description.title.markdown'},
        11: {name: 'punctuation.definition.string.begin.markdown'},
        12: {name: 'punctuation.definition.string.end.markdown'},
        13: {name: 'string.other.link.description.title.markdown'},
        14: {name: 'punctuation.definition.string.begin.markdown'},
        15: {name: 'punctuation.definition.string.end.markdown'},
        16: {name: 'punctuation.definition.metadata.markdown'},
        2: {name: 'string.other.link.title.markdown'},
        4: {name: 'punctuation.definition.string.end.markdown'},
        5: {name: 'invalid.illegal.whitespace.markdown'},
        6: {name: 'punctuation.definition.metadata.markdown'},
        7: {name: 'punctuation.definition.link.markdown'},
        8: {name: 'markup.underline.link.markdown'},
        9: {name: 'punctuation.definition.link.markdown'}
      },
      match:
        '(?x)\n(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\]) # Match the link text.\n([ ])?            # Space not allowed\n(\\()             # Opening paren for url\n(<?)(.*?)(>?)     # The url\n[ \\t]*           # Optional whitespace\n(?:\n  ((\\().+?(\\))) # Match title in parens…\n  | ((").+?("))   # or in quotes.\n)?                # Title is optional\n\\s*              # Optional whitespace\n(\\))',
      name: 'meta.link.inline.markdown'
    },
    'link-ref': {
      captures: {
        1: {name: 'punctuation.definition.string.begin.markdown'},
        2: {name: 'string.other.link.title.markdown'},
        4: {name: 'punctuation.definition.string.end.markdown'},
        5: {name: 'punctuation.definition.constant.begin.markdown'},
        6: {name: 'constant.other.reference.link.markdown'},
        7: {name: 'punctuation.definition.constant.end.markdown'}
      },
      match:
        '(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)([^\\]]*+)(\\])',
      name: 'meta.link.reference.markdown'
    },
    'link-ref-literal': {
      captures: {
        1: {name: 'punctuation.definition.string.begin.markdown'},
        2: {name: 'string.other.link.title.markdown'},
        4: {name: 'punctuation.definition.string.end.markdown'},
        5: {name: 'punctuation.definition.constant.begin.markdown'},
        6: {name: 'punctuation.definition.constant.end.markdown'}
      },
      match:
        '(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)(\\])',
      name: 'meta.link.reference.literal.markdown'
    },
    'list-paragraph': {
      patterns: [
        {
          begin: '\\G\\s+(?=\\S)',
          end: '^\\s*$',
          name: 'meta.paragraph.list.markdown',
          patterns: [
            {include: '#inline'},
            {
              captures: {
                1: {name: 'punctuation.definition.list_item.markdown'}
              },
              match: '^\\s*([*+-]|[0-9]+\\.)'
            }
          ]
        }
      ]
    },
    raw: {
      captures: {
        1: {name: 'punctuation.definition.raw.markdown'},
        3: {name: 'punctuation.definition.raw.markdown'}
      },
      match: '(`+)([^`]|(?!(?<!`)\\1(?!`))`)*+(\\1)',
      name: 'markup.raw.inline.markdown'
    },
    separator: {
      match: '\\G[ ]{0,3}([-*_])([ ]{0,2}\\1){2,}[ \\t]*$\\n?',
      name: 'meta.separator.markdown'
    }
  },
  scopeName: 'source.litcoffee'
}

export default grammar
